package org.mindrive.system.service.system;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.mindrive.system.collection.system.UploadEntity;
import org.mindrive.system.parameter.system.UploadContinueMergeParameter;
import org.mindrive.system.parameter.system.UploadToTempParameter;
import org.mindrive.system.service.BaseService;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class UploadService extends BaseService {

	/**
	 * 上传合并后文档
	 * 
	 * @param file
	 * @param parameter
	 * @return
	 * @throws IOException
	 */
	public void bigFile(MultipartFile file, UploadToTempParameter parameter) {
		String filePath = destPath + File.separator + APP_FILES + File.separator;
		try {
			// 临时目录用来存放所有分片文件
			String tempFileDir = filePath + parameter.getMd5();
			File parentFileDir = new File(tempFileDir);
			if (!parentFileDir.exists()) {
				parentFileDir.mkdirs();
			}
			// 分片处理时，前台会多次调用上传接口，每次都会上传文件的一部分到后台
			File tempPartFile = new File(parentFileDir, parameter.getMd5() + "_" + parameter.getChunk() + ".part");
			FileUtils.copyInputStreamToFile(file.getInputStream(), tempPartFile);
			QueryWrapper<UploadEntity> query = new QueryWrapper<UploadEntity>();
			query.eq("md5", parameter.getMd5());
			UploadEntity uploadEntity = uploadDao.getOne(query);
			if (uploadEntity == null) {
				UploadEntity uploadEntityNew = new UploadEntity();
				uploadEntityNew.setMd5(parameter.getMd5());
				uploadEntityNew.setDivisionCount(parameter.getChunks());
				uploadDao.save(uploadEntityNew);
			}

		} catch (Exception e) {
			log.error("上传失败。", e);
		}
	}

	/**
	 * 返回已上传信息
	 * 
	 * @param md5
	 * @return
	 */
	public Map<String, Object> checkshard(String md5) {
		Map<String, Object> map = new HashMap<String, Object>();
		String filePath = destPath + File.separator + APP_FILES + File.separator;
		File filexmlFolder = new File(filePath);
		if (!filexmlFolder.exists()) {// 如果文件夹不存在
			filexmlFolder.mkdir();// 创建文件夹
		}
		String mergeFilePath = filePath + MERGE + File.separator + md5;
		File mergeFile = new File(mergeFilePath);
		if (!mergeFile.exists()) {
			File dir = new File(filePath + File.separator + md5);
			File[] childs = dir.listFiles();
			List<Integer> strArr = new ArrayList<Integer>();
			if (childs != null) {
				int str = -1;
				for (int i = 0; i < childs.length; i++) {
					int startIndex = childs[i].getPath().toString().lastIndexOf("_");
					int endIndex = childs[i].getPath().toString().lastIndexOf(".");
					str = Integer.parseInt(childs[i].getPath().toString().substring(startIndex + 1, endIndex));
					strArr.add(str);
				}
			}
			Integer chunks = null;
			if (strArr.size() != 0) {
				QueryWrapper<UploadEntity> query = new QueryWrapper<UploadEntity>();
				query.eq("md5", md5);
				UploadEntity ue = uploadDao.getOne(query);
				chunks = ue.getDivisionCount();
			}
			map.put("done", "0");
			map.put("chunks", chunks);
			map.put("existList", strArr);
		} else {
			map.put("done", "1");
			map.put("chunks", 1);
			map.put("existList", 1);
		}

		return map;
	}

	/**
	 * 合并文件
	 * 
	 * @param parameter
	 * @return
	 */
	public String mergeFile(UploadContinueMergeParameter parameter) {
		String filePath = destPath + File.separator + APP_FILES;
		String mergefilePath = filePath + File.separator + MERGE;
		File mergefilePathFile = new File(mergefilePath);
		String md5 = parameter.getMd5();
		if (!mergefilePathFile.exists()) {
			mergefilePathFile.mkdir();
		}
		try {
			String fileName = parameter.getFilename();
			File parentFileDir = new File(filePath + File.separator + md5);
			File destTempFilePath = new File(mergefilePath + File.separator + md5);
			if (!destTempFilePath.exists()) {
				destTempFilePath.mkdir();
			}
			File destTempFile = new File(destTempFilePath + File.separator + fileName);
			try {
				destTempFile.createNewFile();
			} catch (IOException e) {
				e.printStackTrace();
			}
			for (int i = 0; i < parentFileDir.listFiles().length; i++) {
				File partFile = new File(parentFileDir, md5 + "_" + i + ".part");
				FileOutputStream destTempfos = new FileOutputStream(destTempFile, true);
				FileUtils.copyFile(partFile, destTempfos);
				destTempfos.close();
			}
			// 删除临时目录中的分片文件
			FileUtils.deleteDirectory(parentFileDir);
			QueryWrapper<UploadEntity> query = new QueryWrapper<UploadEntity>();
			query.eq("md5", md5);
			uploadDao.remove(query);
		} catch (Exception e) {
			log.error("合并文件失败。", e);
			e.printStackTrace();
		}
		return md5;

	}

	public void uploadCancel(UploadContinueMergeParameter parameter) {
		String filePath = destPath + File.separator + APP_FILES;
		String mergefilePath = filePath + File.separator + MERGE;
		File mergefilePathFile = new File(mergefilePath);
		String md5 = parameter.getMd5();
		String fileName = parameter.getFilename();
		File parentFileDir = new File(filePath + File.separator + md5);
		try {
			FileUtils.deleteDirectory(parentFileDir);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
